﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Web.Security;

namespace ParangonBiz.Tools
{
	public class CryptoHelper
	{
		public static string GetMd5Sum(string data)
		{
			byte[] input = Encoding.Default.GetBytes(data);
			byte[] result = MD5.Create().ComputeHash(input);

			return Convert.ToBase64String(result);
		}

		public static byte[] Encrypt(string data)
		{
			if (Helper.resCryptoKey != null && Helper.resCryptoIV != null)
			{
				return EncryptStringToBytes(data, Convert.FromBase64String(Helper.resCryptoKey),
											Convert.FromBase64String(Helper.resCryptoIV));
			}
			throw new NullReferenceException("Key or IV is null!!!");
		}

		public static string Decrypt(byte[] protectedData)
		{
			if (Helper.resCryptoKey != null && Helper.resCryptoIV != null)
			{
				return DecryptStringFromBytes(protectedData, Convert.FromBase64String(Helper.resCryptoKey),
											  Convert.FromBase64String(Helper.resCryptoIV));
			}
			throw new NullReferenceException("Key or IV is null!!!");
		}

		private static byte[] EncryptStringToBytes(object data, byte[] key, byte[] iv)
		{
			if (data != null)
			{
				byte[] encrypted;

				using (Rijndael rijAlg = Rijndael.Create())
				{
					rijAlg.Key = key;
					rijAlg.IV = iv;

					ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

					using (MemoryStream msEncrypt = new MemoryStream())
					{
						using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
						{
							using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
							{
								swEncrypt.Write(data);
							}
							encrypted = msEncrypt.ToArray();
						}
					}
				}
				return encrypted;
			}
			throw new ArgumentNullException("data");
		}

		private static string DecryptStringFromBytes(byte[] cipherText, byte[] key, byte[] iv)
		{
			if (cipherText != null && cipherText.Length > 0)
			{
				string plaintext;

				using (Rijndael rijAlg = Rijndael.Create())
				{
					rijAlg.Key = key;
					rijAlg.IV = iv;

					ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

					using (MemoryStream msDecrypt = new MemoryStream(cipherText))
					{
						using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
						{
							using (StreamReader srDecrypt = new StreamReader(csDecrypt))
							{
								plaintext = srDecrypt.ReadToEnd();
							}
						}
					}
				}
				return plaintext;
			}
			throw new ArgumentNullException("cipherText");
		}

		public static string CreatePasswordHash(string pwd, string salt)
		{
			string saltAndPwd = String.Concat(pwd, salt);
			string hashedPwd =
					FormsAuthentication.HashPasswordForStoringInConfigFile(
					saltAndPwd, "sha1");
			return hashedPwd;
		}

		public static string CreateSalt()
		{
			RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
			byte[] buff = new byte[32];
			rng.GetBytes(buff);

			return Convert.ToBase64String(buff);
		}
	}
}
